/*
 * Copyright (c) 2021. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
 * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
 * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
 * Vestibulum commodo. Ut rhoncus gravida arcu.
 */

import com.xxpure.Point.MyPoint;
import com.xxpure.Point.PointFactory;
import com.xxpure.compare.KMeansCompare;
import com.xxpure.kmeans.KMeans;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYDataItem;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.ArrayList;

/**
 * @program: KNN
 * @author: Mr.xiao
 * @email: 1347772729@qq.com
 * @create: 2021-07-05 14:19
 **/
public class PointView extends JFrame {
    private static KMeans<MyPoint> means;
    private static KMeansCompare compare;
    private final int bound;
    private final int k;
    private final XYSeries[] pointPanels;
    private ArrayList<MyPoint>[] C;

    public PointView(int bound, ArrayList<MyPoint>[] C, int k) {
        super();
        this.bound = bound;
        this.C = C;
        this.k = k;
        pointPanels = new XYSeries[k];
        for (int i = 0; i < k; i++) {
            pointPanels[i] = new XYSeries(i + 1);
        }
        update();
        final ChartPanel chartPanel = createDemoPanel();
        this.add(chartPanel, BorderLayout.CENTER);
        JPanel jpanel = new JPanel();
        jpanel.add(new JButton(new AbstractAction("下一步") {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    means.nextSample(compare);
                } catch (Exception exception) {
                    JOptionPane.showMessageDialog(null, exception.getMessage());
                    return;
                }
                for (int i = 0; i < k; i++) {
                    pointPanels[i].clear();
                }
                update();
            }
        }));
        this.add(jpanel, BorderLayout.SOUTH);
    }

    public static void main(String[] args) {
        var pointFactory = new PointFactory(1001, 10000);
        means = new KMeans<MyPoint>(pointFactory.getInitialData(), 3);
        compare = new KMeansCompare();
        try {
            means.nextSample(compare);
        } catch (Exception e) {
            e.printStackTrace();
        }
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                var demo = new PointView(1001, means.getC(), means.getSamples().size());
                demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                demo.pack();
                demo.setLocationRelativeTo(null);
                demo.setVisible(true);
            }
        });
    }

    private void update() {
        C = means.getC();
        for (int i = 0; i < k; i++) {
            for (var data : C[i]) {
                pointPanels[i].add(new XYDataItem(data.getX(), data.getY()));
            }
        }

    }

    private ChartPanel createDemoPanel() {
        JFreeChart jfreechart = ChartFactory.createScatterPlot(
                "", "", "", createSampleData(),
                PlotOrientation.VERTICAL, true, true, false);
        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis();
        domain.setRange(0, bound);
        domain.setTickUnit(new NumberTickUnit(1));
        NumberAxis range = (NumberAxis) xyPlot.getRangeAxis();
        range.setRange(0, bound);
        range.setTickUnit(new NumberTickUnit(1));
        return new ChartPanel(jfreechart) {

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(640, 480);
            }
        };
    }

    private XYDataset createSampleData() {
        XYSeriesCollection xySeriesCollection = new XYSeriesCollection();
        for (int i = 0; i < k; i++)
            xySeriesCollection.addSeries(pointPanels[i]);
        return xySeriesCollection;
    }
}
